type ListenerMap = {[k:string]:Fn[]}
type Fn = (...a:any[])=>void
export default class Evt {
	private _event:ListenerMap
	constructor(){
		this._event = {}
	}
	private getListeners(en:string){
		return this._event[en]||(this._event[en]=[])
	}
	on(en:string,fn:Fn):Evt{
			this.getListeners(en).push(fn)
			return this
	}
	once(en:string,fn:Fn):Evt{
		const fn1 = (...a:unknown[])=>{
			this.off(en,fn1)
			fn(...a)
		}
		this.getListeners(en).push(fn1)
		return this
	}
	off(en:string,fn?:Fn):void{
		if(fn)
		this._event[en] = this.getListeners(en).filter(cb=>fn!==cb)
		else this._event[en] = []
	}
	emit(en:string,...a:unknown[]):Evt{
		const fns = this._event[en]
		if(fns)
			fns.forEach(fn=>fn(...a))
		return this
	}
}